home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char RCSid[] = "$Header: QD:ups/ups2/RCS/ups.c,v 1.8 1986/12/11 15:58:18 scooter Exp alph $";
- #endif
-
- /*
- * ups - user interface to the package delivery system
- *
- * usage: ups user@host file1 file2 ...
- *
- * $Author: scooter $
- * $Revision: 1.8 $
- * $Date: 1986/12/11 15:58:18 $
- *
- * $Log: ups.c,v $
- * Revision 1.8 86/12/11 15:58:18 scooter
- * Added alias expansion code which allows ups to follow /usr/lib/aliases.
- *
- * Revision 1.7 86/09/19 18:53:15 scooter
- * Added -i option for mail specification
- *
- * Revision 1.6 86/09/18 15:19:45 scooter
- * More fixes to the '.' problam
- *
- * Revision 1.5 86/09/17 09:43:38 scooter
- * Added code to do automatic renaming of "." files for delivery to
- * avoid the "cannot delete" problem
- *
- * Revision 1.4 85/08/21 22:27:45 scooter
- * Release revision: added more complete RCS headers.
- *
- */
-
- #ifdef amigados
- #include "sys.h"
- #endif
-
- #include <stdio.h>
- #include <pwd.h>
- #include <ndbm.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <sys/file.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <ctype.h>
-
- #ifdef amigados
- #include "ups_protos.h"
- #endif
-
- #define LS "/bin/ls"
-
- struct passwd *getpwuid();
- FILE *fopen();
- int rem;
- int qflg = 0;
- int iflg = 0;
- int on = 1;
- char buffer[BUFSIZ*5];
- char mbuffer[BUFSIZ*4];
-
- struct user_list {
- char *u_user;
- char *u_host;
- struct user_list *u_next;
- };
-
- #ifdef KR
- main(argc, argv)
- char **argv;
- int argc;
- #else
- int main(int argc, char **argv)
- #endif
- {
- char myhost[BUFSIZ];
- int file;
- int ret;
- #ifdef amigados
- char *user,*host,*tmp;
- #else
- char *user,*host,*tmp,*rindex(),*index();
- #endif
- struct passwd *mypwent;
- #ifdef amigados
- struct user_list *u_top, *alias_expand();
- struct user_list dummy_user;
- #else
- struct user_list *u_list,*u_top, *alias_expand();
- #endif
- #ifdef amigados
- if(1)
- {
- char *env;
-
- env = getenv("HOSTNAME");
- if(!env)
- {
- fprintf(stderr, "HOSTNAME not set\n");
- exit(1);
- }
- strncpy(myhost, env, BUFSIZ);
- env = getenv("USERNAME");
- if(!env)
- {
- fprintf(stderr, "USERNAME not set\n");
- exit(1);
- }
- mypwent = malloc(sizeof(struct passwd));
- memset(mypwent, 0, sizeof(struct passwd));
- mypwent->pw_passwd = strdup("");
- mypwent->pw_shell = strdup("");
- mypwent->pw_name = strdup(env);
- mypwent->pw_gecos = strdup("Amiga OS Power User");
- }
- #else
- gethostname(myhost,BUFSIZ);
- if( (mypwent = getpwuid(getuid())) == NULL )
- {
- fprintf(stderr,"ups: who are you?\n");
- exit(1);
- }
- #endif
- argv++;
- argc--;
- while (argc && *argv[0] == '-')
- {
- char c;
-
- switch (c = argv[0][1])
- {
-
- case 'q':
- qflg++;
- break;
-
- case 'i':
- iflg++;
- break;
-
- default:
- fprintf(stderr,"ups: unknown option %c\n",c);
-
- }
- argv++;
- argc--;
- }
-
- if (argc <= 1 || qflg)
- upsread(mypwent);
-
- if (argc < 2)
- {
- fprintf(stderr,"usage: ups user@host file1 file2 ...\n");
- exit(0);
- }
-
- /*
- * Get the name of the destination user and host
- */
-
- user = argv[0];
- host = rindex(user,'@');
- fprintf(stderr, "user = %s\n", user);
- #ifndef ALIASES
- if (host == NULL)
- host = myhost;
- else
- *host++ = '\0';
-
- u_top = &dummy_user;
- dummy_user.u_next = 0;
- dummy_user.u_user = user;
- dummy_user.u_host = host;
- #else
- if (host != NULL)
- *host++ = '\0';
-
- u_top = alias_expand(user,host,myhost);
- #endif /* ALIASES */
-
- #ifdef DEBUG
- printf("Here we are again\n");
- #endif
-
- if (iflg)
- upsgetmsg(mbuffer);
- else
- mbuffer[0] = '\0';
-
- while(u_top != NULL)
- {
-
- #ifdef DEBUG
- printf("Connecting to %s for user %s\n",u_top->u_host,u_top->u_user);
- #endif
- rem = upsconnect(u_top->u_host); /* Connect to the server */
-
- /*
- * Send the to name, from name, and our name
- */
-
- tmp = index(mypwent->pw_gecos,',');
- if (tmp)
- *tmp = '\0';
-
- sprintf(buffer, "%s\n%s\n%s\n%s", u_top->u_user,
- mypwent->pw_name, mypwent->pw_gecos,mbuffer);
-
- #ifdef DEBUG
- printf("Sending: %s\n",buffer);
- fflush(stdout);
- #endif /* DEBUG */
-
- write(rem, buffer, strlen(buffer)+1);
- ret = read(rem, buffer, BUFSIZ);
- if (buffer[0])
- problem(1);
-
- for (file = 1 ; file < argc ; file++)
- {
-
- #ifdef DEBUG
- printf("Sending file: %s\n",argv[file]);
- #endif /* DEBUG */
-
- sendfile(argv[file]);
- }
-
- sprintf(buffer, "-Done-");
- write(rem, buffer, strlen(buffer)+1);
- read(rem, buffer, BUFSIZ); /* get result */
- if (buffer[0]) /* problem? */
- problem(1); /* yes, go handle it */
-
- close(rem);
- u_top = u_top->u_next;
- }
-
- }
-
-
-
-
- upsconnect(host)
- char *host;
- {
- struct hostent *hp;
- struct servent *sp;
- struct sockaddr_in sin;
- int s;
-
- hp = gethostbyname(host);
- if (hp == NULL) {
- static struct hostent def;
- static struct in_addr defaddr;
- static char namebuf[128];
- #ifndef amigados
- int inet_addr();
- #endif
-
- defaddr.s_addr = inet_addr(host);
- if (defaddr.s_addr == -1) {
- printf("unknown host: %s\n", host);
- exit(1);
- }
- strcpy(namebuf, host);
- def.h_name = namebuf;
- def.h_addr = (char *)&defaddr;
- def.h_length = sizeof (struct in_addr);
- def.h_addrtype = AF_INET;
- def.h_aliases = 0;
- hp = &def;
- }
- sp = getservbyname("ups", "tcp");
- if (sp == 0) {
- fprintf(stderr,"tcp/ups: unknown service\n");
- exit(1);
- }
- sin.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
- sin.sin_port = sp->s_port;
- s = socket(hp->h_addrtype, SOCK_STREAM, 0);
- if (s < 0) {
- fflush(stderr);
- perror("ups (socket)");
- exit(1);
- }
- setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&on,sizeof(on));
- #ifdef DEBUG
- setsockopt(s,SOL_SOCKET,SO_DEBUG,&on,sizeof(on));
- #endif /* DEBUG */
- if (connect(s, (char *)&sin, sizeof (sin)) < 0) {
- fflush(stderr);
- perror("ups (connect)");
- close(s);
- exit(1);
- }
- return(s);
- }
-
-
-
-
- sendfile(file)
- char *file;
- {
- struct stat fstatus;
- int loc,n;
- char *tmp,*fname;
-
- if ( (loc = open(file,O_RDONLY)) <= 0 ) {
- perror("ups (open)");
- return(1);
- }
- if (fstat(loc, &fstatus)) {
- perror("ups (fstat)");
- return(1);
- }
-
- if ((fstatus.st_mode&S_IFMT) != S_IFREG) {
- switch (fstatus.st_mode&S_IFMT)
- {
- case S_IFDIR:
- tmp = "directory";
- break;
- #ifdef S_IFCHR
- case S_IFCHR:
- tmp = "character device";
- break;
- case S_IFBLK:
- tmp = "block device";
- break;
- #endif
- #ifdef S_IFLNK
- case S_IFLNK:
- tmp = "symbolic link";
- break;
- #endif
- #ifdef S_IFSOCK
- case S_IFSOCK:
- tmp = "socket";
- break;
- #endif
- }
-
- fprintf(stderr,
- "ups: %s is a %s, only regular files may be sent\n",
- file,tmp);
- fflush(stderr);
- return(1);
- }
-
- /*
- * Send the file name
- */
-
- /*
- * First strip off the directory path
- */
- sprintf(buffer,"%s",file);
- #ifndef amigados
- tmp = rindex(buffer,'/');
- if (tmp)
- *tmp++ = '\0';
- else
- tmp = buffer;
- #else
- tmp = rindex(buffer,'/');
- if (tmp)
- *tmp++ = '\0';
- else
- {
- tmp = rindex(buffer,':');
- if (tmp)
- *tmp++ = '\0';
- else
- tmp = buffer;
- }
- #endif
- fname = tmp;
-
- if (*tmp == '.')
- {
- while ( (*tmp == '.') && (*tmp != '\0') )tmp++;
-
- fprintf(stdout,
- "WARNING: file %s has been renamed to %s for delivery\n",
- fname,tmp);
- }
-
- write(rem, tmp, strlen(tmp)+1);
- read(rem, buffer, BUFSIZ);
- if (buffer[0]) /* problem */
- {
- problem(0);
- return(1);
- }
-
- /*
- * Send the file size in bytes
- */
-
- sprintf(buffer, "%d",fstatus.st_size);
- write(rem, buffer, strlen(buffer)+1);
- read(rem, buffer, BUFSIZ);
- if (buffer[0]) /* problem */
- {
- problem(0);
- return(1);
- }
-
- /*
- * Send the file
- */
- while (n = read(loc, buffer, BUFSIZ))
- write(rem, buffer, n);
- close(loc);
- read(rem, buffer, BUFSIZ); /* get result */
- if (buffer[0]) /* problem */
- {
- problem(0);
- return(1);
- }
- #ifndef amigados
- sprintf(buffer, "%u", fstatus.st_mode);
- #else /* use unix modes for transmission*/
- {
- int unix_mode=0, ami_mode;
-
- ami_mode = fstatus.st_mode;
-
- if(ami_mode & 8)
- unix_mode |= 0400;
- if(ami_mode & 5)
- unix_mode |= 0200;
- if(ami_mode & 2)
- unix_mode |= 0100;
-
- sprintf(buffer, "%u", unix_mode);
- }
- #endif
- write(rem, buffer, strlen(buffer)+1);
- read(rem, buffer, BUFSIZ); /* get result */
- if (buffer[0]) /* problem */
- {
- problem(0);
- return(1);
- }
- return(0);
- }
-
-
-
- upsread(mypwent)
- struct passwd *mypwent;
- {
- #ifndef amigados
- union wait status;
- int pid;
- char c;
- #endif
- char line[BUFSIZ],*tmp;
- #ifdef amigados
- strmfp(buffer,UPSDIR,mypwent->pw_name);
- #else
- sprintf(buffer,"%s/%s",UPSDIR,mypwent->pw_name);
- #endif
- if (qflg)
- {
- if (!access(buffer,F_OK)) {
- fprintf(stderr,
- "You have ups files awaiting you (type ups to accept delivery)\n");
- }
- exit(0);
- }
- if (access(buffer,F_OK)) {
- fprintf(stderr,"Nothing waiting in ups\n");
- exit(0);
- }
- fprintf(stdout,"\nYou have the following files awaiting delivery:\n\n");
- #ifdef amigados
- {
- char lbuf[BUFSIZ];
-
- sprintf(lbuf, "list %s", buffer);
- system(lbuf);
- }
- #else
- if (pid = vfork())
- {
- wait(&status);
- } else {
- execl(LS,"ls","-C",buffer,(char *)0);
- perror("ups (exec)");
- return(0);
- }
- #endif
- fprintf(stdout,"\n");
-
- fprintf(stdout,
- "Do you wish to accept delivery in your\n");
- #ifdef amigados
- fprintf(stdout,
- "current directory (%s)? ",
- getcwd(line, BUFSIZ));
- #else
- fprintf(stdout,
- "current directory (%s)? ",
- getwd(line));
- #endif
-
- getinp:
- if (fgets(line,BUFSIZ,stdin) == NULL) {
- fprintf(stdout,"\n");
- exit(0);
- }
-
- tmp = &line[0];
- while (isspace(*tmp)) tmp++;
-
- switch (*tmp) {
- case 'y':
- case 'Y':
- #ifndef amigados
- sprintf(line,"mv -i %s/* . ; rmdir %s",buffer,buffer);
- system(line);
- #else
- sprintf(line,"copy %s/#? \"\"",buffer);
- if(!system(line))
- {
- sprintf(line,"c:delete %s ALL FORCE",buffer);
- system(line);
- }
- #endif
- exit(0);
-
- case 'n':
- case 'N':
- exit(0);
-
- default:
- fprintf(stdout,"Please answer 'yes' or 'no': ");
- goto getinp;
- }
- }
-
-
-
- /*
- * problem() is called when the install demon process return a non-zero reply.
- * This usually means something recognizable went wrong and we should expect
- * a reason to follow. Read in the reason, output it on the terminal and die.
- */
-
- problem(die)
- int die;
- {
- char buf[BUFSIZ]; /* place to read into */
-
- if (read(rem, buf, BUFSIZ) > 0) /* if we have something */
- fprintf(stderr, "ups: %s", buf);
- if (die) {
- close(rem); /* close network channel */
- exit(1);
- }
- }
-
- int
- upsgetmsg(mailbuffer)
- char *mailbuffer;
- {
- int done = 0;
-
- fprintf(stdout,
- "Enter your message followed by '.<RETURN>' or a <CTRL>D:\n");
-
- while (!done)
- {
- fprintf(stdout,"> ");
- if (gets(mailbuffer) == NULL)
- {
- fprintf(stdout,"\n");
- done++;
- } else if ( (*mailbuffer == '.') && (*(mailbuffer+1) == '\0'))
- {
- done++;
- *mailbuffer = '\0';
- } else {
- while(*mailbuffer != '\0')
- mailbuffer++;
- *mailbuffer++ = '\n';
- *mailbuffer = '\0';
- }
- }
- fprintf(stdout,"[EOT]\n");
- }
-
-
-
- #ifdef ALIASES
- struct user_list *
- alias_expand(user,host,myhost)
- char *user,*host,*myhost;
- {
- #ifndef amigados
- char *malloc();
- #endif
- DBM *dp;
- datum key,content;
- struct user_list *list,*top,*alloc_list();
- char *cp,*tp,*hp;
-
- list = top = (struct user_list *)NULL;
-
- if (host != NULL)
- return(alloc_list(user,host));
-
- dp = dbm_open("/usr/lib/aliases", O_RDONLY, 0644);
-
- if (dp == NULL) {
- if(host == NULL)
- return(alloc_list(user, myhost));
- else
- return(alloc_list(user, host));
- }
-
- key.dptr = user;
- key.dsize = strlen(user) + 1;
-
- content = dbm_fetch(dp,key);
- if (content.dptr == NULL)
- return(alloc_list(user,myhost));
- cp = content.dptr;
-
- while (cp != NULL)
- {
- tp = cp;
- cp = index(cp,',');
- if (cp != NULL)
- *cp++ = '\0';
- if (index(tp,'!')) {
- fprintf(stderr,
- "ups: WARNING: cannot alias %s to %s (no ups over uucp)\n",
- user,hp);
- continue;
- } else if(index(tp,'|')) {
- fprintf(stderr,
- "ups: WARNING: cannot alias %s to %s (no shells allowed)\n",
- user,hp);
- continue;
- }
- hp = tp;
- hp = index(tp,'@');
- if (hp == NULL)
- hp = myhost;
- else
- *hp++ = '\0';
- if (top == NULL)
- top = list = alloc_list(tp,hp);
- else
- {
- list->u_next = alloc_list(tp,hp);
- list = list->u_next;
- }
- }
- return(top);
- }
- #endif
-
- struct user_list *alloc_list(user,host)
- char *user,*host;
- {
- #ifndef amigados
- char *malloc();
- #endif
- struct user_list *list;
-
- list = (struct user_list *)malloc(sizeof(struct user_list));
- list->u_user = malloc(strlen(user) + 1);
- list->u_host = malloc(strlen(host) + 1);
- strcpy(list->u_user,user);
- strcpy(list->u_host,host);
- list->u_next = (struct user_list *)NULL;
- return(list);
- }
-